package com.work.cos.service.impl.pay;

import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.work.cos.domain.vo.ComMemoryCacheContext;
import com.work.cos.util.constants.Constants;
import com.work.cos.util.thirdpay.weixinpay.config.WeixinConfig;
import com.work.cos.util.thirdpay.weixinpay.util.HttpUtil;
import com.work.cos.util.thirdpay.weixinpay.util.PayCommonUtil;
import com.work.cos.util.thirdpay.weixinpay.util.XMLUtil;

/**
 *类功能说明：
 */
@Service
public class WeixinServiceImpl {




    public static String PAY_API = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    static final Logger logger = LoggerFactory.getLogger(WeixinServiceImpl.class);

	/**
     * 微信支付统一下单接口
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    public static String weixin_pay(String out_trade_no) throws Exception {
        // 账号信息
        String appid = WeixinConfig.APP_ID;  // appid
        //String appsecret = PayConfigUtil.APP_SECRET; // appsecret
        // 商业号
        String mch_id = WeixinConfig.MCH_ID;
        // key
        String key = WeixinConfig.API_KEY;

        String currTime = PayCommonUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayCommonUtil.buildRandom(4) + "";
        //随机字符串
        String nonce_str = strTime + strRandom;
        // 价格   注意：价格的单位是分
        //String order_price = "1";
        // 商品名称
        //String body = "企嘉科技商品";

        //查询订单数据表获取订单信息
//        PayOrder payOrder = payOrderDao.get(PayOrder.class,out_trade_no);
        // 获取发起电脑 ip
        String spbill_create_ip ="127.0.0.1";
        // 回调接口
        String notify_url = ComMemoryCacheContext.getObjectFromMemory(Constants.URL_APP_ROOT) + WeixinConfig.notify_url;

//        String notify_url = "http://www.xiaobaiwuyou.com/s/login";
       System.out.println(notify_url+" 回调接口");
        String trade_type = "NATIVE";
        String time_start =  new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        Calendar ca = Calendar.getInstance();
        ca.setTime(new Date());
        ca.add(Calendar.DATE, 1);
        String time_expire =  new SimpleDateFormat("yyyyMMddHHmmss").format(ca.getTime());
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        packageParams.put("nonce_str", nonce_str);
        packageParams.put("body","xiaoba代缴社保");
        packageParams.put("out_trade_no", out_trade_no);
        packageParams.put("total_fee","1");
        packageParams.put("spbill_create_ip", spbill_create_ip);
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);
        packageParams.put("time_start", time_start);
        packageParams.put("time_expire", time_expire);
        String sign = PayCommonUtil.createSign("UTF-8", packageParams,key);
        System.out.println(sign+"签名");
        packageParams.put("sign", sign);

        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        System.out.println("请求xml：：：："+requestXML);

        String resXml = HttpUtil.postData(WeixinConfig.UNIFIED_ORDER_URL, requestXML);
        System.out.println("返回xml：：：："+resXml);

        Map map = XMLUtil.doXMLParse(resXml);
        System.out.println(map.get("err_code")+"错误条件");
        //String return_code = (String) map.get("return_code");
        //String prepay_id = (String) map.get("prepay_id");
        String urlCode = (String) map.get("code_url");
        System.out.println("打印调用统一下单接口生成二维码url:::::"+urlCode);
        return urlCode;
}



    /**
     * 回调接口处理信息
     * @param request
     * @param response
     * @throws Exception
     */
 public static Map<String, String>  weixin_notify(HttpServletRequest request,HttpServletResponse response) throws Exception{

	 Map<String, String> map=new HashMap<String,String>();
        //读取参数
        InputStream inputStream ;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s ;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null){
            sb.append(s);
        }
        in.close();
        inputStream.close();

        //解析xml成map
        Map<String, String> m = new HashMap<String, String>();
        m = XMLUtil.doXMLParse(sb.toString());

        //过滤空 设置 TreeMap
        SortedMap<Object,Object> packageParams = new TreeMap<Object,Object>();
        Iterator it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = (String) it.next();
            String parameterValue = m.get(parameter);

            String v = "";
            if(null != parameterValue) {
                v = parameterValue.trim();
            }
            packageParams.put(parameter, v);
        }

        // 账号信息
        String key = WeixinConfig.API_KEY; // key

        logger.info(packageParams.toString());
        //判断签名是否正确
        if(PayCommonUtil.isTenpaySign("UTF-8", packageParams,key)) {
            //------------------------------
            //处理业务开始
            //------------------------------
            String resXml = "";
            if("SUCCESS".equals((String)packageParams.get("result_code"))){
                // 这里是支付成功


                //////////执行自己的业务逻辑////////////////
                String mch_id = (String)packageParams.get("mch_id");
                String openid = (String)packageParams.get("openid");
                String is_subscribe = (String)packageParams.get("is_subscribe");
                String out_trade_no = (String)packageParams.get("out_trade_no");

                String total_fee = (String)packageParams.get("total_fee");

                logger.info("mch_id:"+mch_id);
                logger.info("openid:"+openid);
                logger.info("is_subscribe:"+is_subscribe);
                logger.info("out_trade_no:"+out_trade_no);
                logger.info("total_fee:"+total_fee);

                //////////执行自己的业务逻辑////////////////

                logger.info("支付成功");
                //通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";

                BufferedOutputStream out = new BufferedOutputStream(
                        response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
                  map.put("status", "true");
                  map.put("orderNum", out_trade_no);
                  map.put("price", total_fee);
                return map;
            } else {
                logger.info("支付失败,错误信息：" + packageParams.get("err_code"));
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";

                BufferedOutputStream out = new BufferedOutputStream(
                        response.getOutputStream());
                out.write(resXml.getBytes());
                out.flush();
                out.close();
                map.put("status", "false");
                return map;

            }
            //------------------------------
            //处理业务完毕
            //------------------------------

        } else{
            logger.info("通知签名验证失败");
        }
		return null;

    }


    /**
     * 生成二维码图片 不存储 直接以流的形式输出到页面
     * @param content
     * @param response
     */
    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void encodeQrcode(String content,HttpServletResponse response){
        if(content==null || "".equals(content))
            return;

       MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
       Map hints = new HashMap();
       hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); //设置字符集编码类型
       BitMatrix bitMatrix = null;
       try {
           bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 300, 300,hints);
           BufferedImage image = toBufferedImage(bitMatrix);
           //输出二维码图片流
           try {
               ImageIO.write(image, "png", response.getOutputStream());
           } catch (IOException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
           }
       } catch (WriterException e1) {
           // TODO Auto-generated catch block
           e1.printStackTrace();
       }
    }

	private static BufferedImage toBufferedImage(BitMatrix bitMatrix) {
		int width = bitMatrix.getWidth();
		int height = bitMatrix.getHeight();
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
			}
		}

//		// 插入图片
//		insertImage(image, imgPath, needCompress);
		return image;
	}

	/**
	 * 插入LOGO
	 *
	 * @param source
	 *            二维码图片
	 * @param imgPath
	 *            LOGO图片地址
	 * @param needCompress
	 *            是否压缩
	 * @throws Exception
	 */
//	private static void insertImage(BufferedImage source, String imgPath, boolean needCompress) throws Exception {
//		File file = new File(imgPath);
//		if (!file.exists()) {
//			System.err.println("" + imgPath + "   该文件不存在！");
//			return;
//		}
//		Image src = ImageIO.read(new File(imgPath));
//		int width = src.getWidth(null);
//		int height = src.getHeight(null);
//		if (needCompress) { // 压缩LOGO
//			if (width > WIDTH) {
//				width = WIDTH;
//			}
//			if (height > HEIGHT) {
//				height = HEIGHT;
//			}
//			Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
//			BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//			Graphics g = tag.getGraphics();
//			g.drawImage(image, 0, 0, null); // 绘制缩小后的图
//			g.dispose();
//			src = image;
//		}
//		// 插入LOGO
//		Graphics2D graph = source.createGraphics();
//		int x = (QRCODE_SIZE - width) / 2;
//		int y = (QRCODE_SIZE - height) / 2;
//		graph.drawImage(src, x, y, width, height, null);
//		Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
//		graph.setStroke(new BasicStroke(3f));
//		graph.draw(shape);
//		graph.dispose();
//	}
//
//	/**
//	 * 生成二维码(内嵌LOGO)
//	 *
//	 * @param content
//	 *            内容
//	 * @param imgPath
//	 *            LOGO地址
//	 * @param destPath
//	 *            存放目录
//	 * @param needCompress
//	 *            是否压缩LOGO
//	 * @throws Exception
//	 */
//	public static void encode(String content, String imgPath, String destPath, boolean needCompress) throws Exception {
//		BufferedImage image = createImage(content, imgPath, needCompress);
//		mkdirs(destPath);
//		String file = new Random().nextInt(99999999) + ".jpg";
//		ImageIO.write(image, FORMAT_NAME, new File(destPath + "/" + file));
//	}
//
//	/**
//	 * 当文件夹不存在时，mkdirs会自动创建多层目录，区别于mkdir．(mkdir如果父目录不存在则会抛出异常)
//	 *
//	 * @author lanyuan Email: mmm333zzz520@163.com
//	 * @date 2013-12-11 上午10:16:36
//	 * @param destPath
//	 *            存放目录
//	 */
//	public static void mkdirs(String destPath) {
//		File file = new File(destPath);
//		// 当文件夹不存在时，mkdirs会自动创建多层目录，区别于mkdir．(mkdir如果父目录不存在则会抛出异常)
//		if (!file.exists() && !file.isDirectory()) {
//			file.mkdirs();
//		}
//	}
//
//	/**
//	 * 生成二维码(内嵌LOGO)
//	 *
//	 * @param content
//	 *            内容
//	 * @param imgPath
//	 *            LOGO地址
//	 * @param destPath
//	 *            存储地址
//	 * @throws Exception
//	 */
//	public static void encode(String content, String imgPath, String destPath) throws Exception {
//		encode(content, imgPath, destPath, false);
//	}
//
//	/**
//	 * 生成二维码
//	 *
//	 * @param content
//	 *            内容
//	 * @param destPath
//	 *            存储地址
//	 * @param needCompress
//	 *            是否压缩LOGO
//	 * @throws Exception
//	 */
//	public static void encode(String content, String destPath, boolean needCompress) throws Exception {
//	encode(content, null, destPath, needCompress);
//	}
//
//	/**
//	 * 生成二维码
//	 *
//	 * @param content
//	 *            内容
//	 * @param destPath
//	 *            存储地址
//	 * @throws Exception
//	 */
//	public static void encode(String content, String destPath) throws Exception {
//		encode(content, null, destPath, false);
//	}
//
//	/**
//	 * 生成二维码(内嵌LOGO)
//	 *
//	 * @param content
//	 *            内容
//	 * @param imgPath
//	 *            LOGO地址
//	 * @param output
//	 *            输出流
//	 * @param needCompress
//	 *            是否压缩LOGO
//	 * @throws Exception
//	 */
//	public static void encode(String content, String imgPath, OutputStream output, boolean needCompress)
//			throws Exception {
//		BufferedImage image = createImage(content, imgPath, needCompress);
//		ImageIO.write(image, FORMAT_NAME, output);
//	}
//
//	/**
//	 * 生成二维码
//	 *
//	 * @param content
//	 *            内容
//	 * @param output
//	 *            输出流
//	 * @throws Exception
//	 */
//	public static void encode(String content, OutputStream output) throws Exception {
//		encode(content, null, output, false);
//	}
//
//	public static void main(String[] args) throws Exception {
//		String text = "test";
//		encode(text, "/Users/noahshen/Downloads/6BFAADD4-256D-447B-B742-1E1DFF11094F_meitu_1.png",
//				"/Users/noahshen/Downloads", true);
//		// QRCodeUtil.encode(text, null, "/Users/noahshen/Downloads", true);
//	}
//
}
